package system

import (
	"fmt"
	"woo-server/coms/structs"
	"woo-server/coms/utils"
	"woo-server/models/db"
)

// 菜单字段表
type AdminMenus struct {
	*structs.Common `gorm:"-" json:"-"`
	AdminMenuId     uint64      `gorm:"primary_key;AUTO_INCREMENT;column:admin_menu_id;"` // 自增主键
	ParentId        uint64      `gorm:"column:parent_id;size:255;"`                       // 父ID
	Name            string      `gorm:"column:name;size:255;"`                            // 菜单名称
	Url             string      `gorm:"column:url;size:255;"`                             // 后端完整router地址 如:/api/Menu/List
	IsHidden        uint        `gorm:"column:is_hidden;size:255;"`                       // 是否隐藏菜单 0:是 1:否
	Icon            string      `gorm:"column:icon;size:50;"`                             // 图标
	Sort            uint        `gorm:"column:sort;size:255;"`                            // 排序 越小越靠前
	WebUrl          string      `gorm:"column:web_url;size:255;"`                         // 前端路由
	Status          uint        `gorm:"column:status;"`                                   // 状态 1:正常 0:禁用
	ChildRen        interface{} //
	Select          []uint64    //
	db.Basics
}

//type AdminMenus struct {
//	*structs.AdminMenus
//}

func (m *AdminMenus) GetConfig() structs.CFConfig {
	list := structs.CFConfig{}
	list.Column = m.Column()
	list.Forms = m.Forms()
	return list
}

func (m *AdminMenus) Column() []structs.ColumnCommon {
	result := make([]structs.ColumnCommon, 0)
	result = append(result, structs.ColumnCommon{Title: "ID", DataIndex: "AdminMenuId"})
	result = append(result, structs.ColumnCommon{Title: "名称", DataIndex: "Name"})
	result = append(result, structs.ColumnCommon{Title: "隐藏", DataIndex: "IsHidden"})
	result = append(result, structs.ColumnCommon{Title: "前端路由", DataIndex: "WebUrl"})
	result = append(result, structs.ColumnCommon{Title: "排序", DataIndex: "Sort"})
	result = append(result, structs.ColumnCommon{Title: "创建时间", DataIndex: "UpdateDate"})
	result = append(result, structs.ColumnCommon{Title: "操作", DataIndex: "Operation"})
	return result
}

func (m *AdminMenus) Forms() []structs.FormsCommon {
	result := make([]structs.FormsCommon, 0)
	var option structs.Options
	var options []structs.Options
	option.Value = 0
	option.Label = "顶级栏目"
	options = append(options, option)
	_, list := m.GetAllMenu(true)
	options = MergeSlice(options, m.SetOption(list, 0))
	result = append(result, structs.FormsCommon{Key: "AdminMenuId", Label: "主键ID", Type: "primary_key", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "ParentId", Label: "上级菜单", Type: "OnceSelect", Options: options})
	result = append(result, structs.FormsCommon{Key: "Name", Label: "菜单名称", Type: "input", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "IsHidden", Label: "是否隐藏", Type: "switch", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "Sort", Label: "排序", Type: "number", Options: []string{}})
	//result = append(result, structs.FormsCommon{Key: "Icon", Label: "Icon", Type: "icon", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "WebUrl", Label: "前端路由", Type: "input", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "Url", Label: "接口API", Type: "input", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "Status", Label: "状态", Type: "switch", Options: []string{}})
	return result
}

// 合并数组
func MergeSlice(s1 []structs.Options, s2 []structs.Options) []structs.Options {
	slice := make([]structs.Options, len(s1)+len(s2))
	copy(slice, s1)
	copy(slice[len(s1):], s2)
	return slice
}

// 表名
func (m *AdminMenus) TableName() string {
	return "woo_admin_menu"
}

// 初始化
func NewMenus(com *structs.Common) *AdminMenus {
	d := &AdminMenus{}

	return d
}

// 创建
func (m *AdminMenus) Create() error {
	return utils.GORM.Debug().Table(m.TableName()).Create(m).Error
}

// 批量创建
func (m *AdminMenus) BatchCreate(data []*AdminMenus) error {
	return utils.GORM.Debug().Table(m.TableName()).Create(data).Error
}

// 获取分页列表及总数
func (m *AdminMenus) GetUserListAndTotal(search string, page int, pageSize int) ([]*AdminMenus, int64) {
	list := make([]*AdminMenus, 0)
	var total int64 = 0

	// 查询
	query := utils.GORM.Debug().Table(m.TableName())
	query = query.Order("sort asc")
	if len(search) > 0 {
		search = fmt.Sprintf("%%%s%%", search)
		query = query.Where("name like ? or no like ? or email like ?", search, search, search)
	}

	// 总数
	query.Count(&total)

	// 列表
	offset := (page - 1) * pageSize
	query.Limit(pageSize).Offset(offset).Find(&list)

	return list, total
}

// 获取所有菜单
// @param isHidden 是否显示
// return treeList 树状菜单 , list 非树状
func (m *AdminMenus) GetAllMenu(isHidden bool) ([]structs.AdminMenus, []AdminMenus) {
	list := make([]AdminMenus, 0)

	// 查询
	query := utils.GORM.Debug().Table(m.TableName())
	query = query.Order("sort asc")
	// 列表
	query.Find(&list)
	//fmt.Println("all menus :", list)
	treeList := MakeRoleMenu(list, 0, isHidden, []uint64{})
	return treeList, list
}

// 获取单数据
func (m *AdminMenus) GetFirst(where string, field int) *AdminMenus {
	//info := make([]*AdminMenus, 0)

	// 查询
	query := utils.GORM.Debug().Table(m.TableName())

	query = query.Where(where, field)

	// 总数
	//query.Count(&total)

	// 列表
	//offset := (page - 1) * pageSize
	query.First(&m)
	return m
}

// 获取用户权限菜单
func (m *AdminMenus) GetRoleMenu(where string, field []int, showHidden bool) ([]structs.AdminMenus, []AdminMenus) {
	list := make([]AdminMenus, 0)

	// 查询
	query := utils.GORM.Debug().Table(m.TableName())
	query = query.Order("sort asc")
	query = query.Where(where, field)

	query.Find(&list)
	treelist := MakeRoleMenu(list, 0, showHidden, []uint64{})
	return treelist, list
}

// 更新菜单
func (m *AdminMenus) Save() error {
	// 更新
	return utils.GORM.Debug().Table(m.TableName()).Save(m).Error
}

// 删除菜单
func (m *AdminMenus) Delete() error {
	return utils.GORM.Debug().Table(m.TableName()).Delete(m).Error
}

// 获取单条数据
func (m *AdminMenus) First() error {
	return utils.GORM.Debug().Table(m.TableName()).First(m).Error
}

func (m *AdminMenus) SetOption(MenuList []AdminMenus, pid uint64) []structs.Options {
	var AdminRoleMenus []structs.Options
	for _, v := range MenuList {
		if v.ParentId == pid {
			//fmt.Println(pid)
			var option structs.Options
			option.Value = v.AdminMenuId
			option.Label = v.Name
			option.ChildRen = m.SetOption(MenuList, v.AdminMenuId)
			//fmt.Println(option)
			AdminRoleMenus = append(AdminRoleMenus, option)
		}
	}
	return AdminRoleMenus
}

/**
递归多级菜单
@param RoleMenu []AdminMenus 要遍历菜单
@param pid uint64 父ID
@param showHidden bool 是否显示隐藏菜单
@param Select []uint64 当前父子ID关联数组
return []AdminMenus
*/
func MakeRoleMenu(RoleMenu []AdminMenus, pid uint64, showHidden bool, Select []uint64) []structs.AdminMenus {
	var AdminRoleMenus []structs.AdminMenus
	for _, v := range RoleMenu {
		if showHidden {
			if v.ParentId == pid {
				//fmt.Println(pid)
				var option structs.AdminMenus
				option.AdminMenuId = v.AdminMenuId
				option.Name = v.Name
				option.ParentId = v.ParentId
				option.Url = v.Url
				option.WebUrl = v.WebUrl
				option.IsHidden = v.IsHidden
				option.Sort = v.Sort
				option.Icon = v.Icon
				option.Status = v.Status
				option.CreateDate = v.CreateDate
				option.UpdateDate = v.UpdateDate
				NewSelect := Select
				if v.ParentId == 0 {
					NewSelect = []uint64{0}
				} else {

					if NewSelect[0] != 0 {
						NewSelect = append(NewSelect, v.ParentId)
					} else {
						NewSelect = []uint64{v.ParentId}
					}
				}
				option.Select = NewSelect
				option.ChildRen = MakeRoleMenu(RoleMenu, v.AdminMenuId, showHidden, NewSelect)
				AdminRoleMenus = append(AdminRoleMenus, option)
			}
		} else {
			if v.ParentId == pid && v.IsHidden == 1 {
				//fmt.Println(pid)
				var option structs.AdminMenus
				option.AdminMenuId = v.AdminMenuId
				option.Name = v.Name
				option.ParentId = v.ParentId
				option.Url = v.Url
				option.WebUrl = v.WebUrl
				option.IsHidden = v.IsHidden
				option.Sort = v.Sort
				option.Icon = v.Icon
				option.Status = v.Status
				option.CreateDate = v.CreateDate
				option.UpdateDate = v.UpdateDate
				option.ChildRen = MakeRoleMenu(RoleMenu, v.AdminMenuId, showHidden, []uint64{})
				//fmt.Println(option)
				AdminRoleMenus = append(AdminRoleMenus, option)
			}
		}
	}
	return AdminRoleMenus
}
